--// colorsets.lua for BCDC++
--// Rev 003/20060219, Szabolcs Molnar; fleet@elitemail.hu

colorset = {}

colorset.settings = {}

colorset.settings.filepat = "*.colset"
colorset.settings.dcppxml = "../../DCPlusPlus.xml"
colorset.settings.fstxt = "../formatting_settings.txt"

function colorset.sendWelcome()
	print("Welcome to colorsets.lua!")
	print("-------------------------\r\n")
	print("This tool helps you to load BCDC++ ColorSets without having to configure the\r\ncolors individually.\r\n")
	print("IMPORTANT: BEFORE LOADING ANY COLORSET, PLEASE EXIT BCDC++, OTHERWISE IT\r\nOVERWRITES YOUR CHANGES ON EXIT!")
	return 0
end

function colorset.showFiles( pat )
	print("--------------------------------")
	os.execute("dir " .. pat .. " /B")
	print("--------------------------------")
	return 0
end

function colorset.showMenu()
	print( " Main menu:" )
	print( "-------------------" )
	print( " [1] Show colorsets" )
	print( " [2] Load colorset" )
	print( " [3] Reprint menu" )
	print( " [X] Quit" )
	print( "-------------------" )
end

function colorset.readFile( filename )
	local sta = true
	local errmsg = "OK"
	local content = {}
	local f, err = io.open( filename )
	if f then
		local text = f:read("*l")
		while( text ) do
			table.insert( content, text )
			text = f:read("*l")
		end
		f:close()
	else
		sta = false
		errmsg = err
	end
	return sta, errmsg, content
end

function colorset.saveFile( filename, txttable )
	local f, err = io.open( filename, "w+" )
	if not f then
		return f, err
	else
		for k in txttable do
			f:write( txttable[k] .. "\n" )
		end
		f:close()
	end
	return true, "OK"
end

-- return true if managed
-- false, plus an error message if not (probably the only reason for this a corrupted dcpp.xml or colorset file)
function colorset.updateXML( xmltable, variable, vartype, value )
	local managed, errmsg = false, "Couldn't set \"" .. variable .. "\" variable. Not found in the XML file."
	if vartype ~= "int" and vartype ~= "string" then
		-- This NEVER shoud happen
		errmsg = "VERY Crazy error. Bzzz"
		return managed, errmsg
	end
	local pattern = "^([%s]*<" .. variable .. " type=\"" .. vartype .. "\">)[^<]+(</" .. variable .. ">[%s]*)$"
	-- print("PATTERN: " .. pattern)
	for k in xmltable do
		if string.find( xmltable[k], pattern ) then
			xmltable[k] = string.gsub( xmltable[k], pattern, "%1" .. value .. "%2")
			managed, errmsg = true, "OK"
		end
	end
	if not managed then
		-- if not upgraded, add itt manually
		for k in xmltable do
			if string.find( xmltable[k], "^[%s]*</Settings>%s*$" ) then
				table.insert(xmltable, k, "\t\t<" .. variable .. " type=\"" .. vartype .. "\">" .. value .. "</" .. variable .. ">"  )
				managed = true
				break
			end
		end
	end
	return managed, errmsg
end

-- return true if managed
-- false, plus an error message if not (probably corrupted formatting_settings.txt or colorset file)
function colorset.updateFS( txttable, variable , value )
	local managed, errmsg = false, "Couldn't set \"" .. variable .. "\" variable. Not found in the .txt file."
	local pattern = "^([%s]*" .. variable .. " = \")[%a%d\\;]*(\",[%s]*)$"
	-- print( "PATTERN: " .. pattern )
	
	-- escaping for \\red\\green\\blue; -type values
	value = string.gsub( value, "\\", "\\\\" )
	
	for k in txttable do
		if string.find( txttable[k], pattern) then
			txttable[k] = string.gsub( txttable[k], pattern, "%1" .. value .. "%2")
			managed, errmsg = true, "OK"
		end
	end
	return managed, errmsg
end

function colorset.loadCS()
	local nice = true
	local errmsg = "OK"
	local ret, err = true, "OK"
	local dcppxml, fstxt = {}, {}
	
	print("Load colorset")
	print("-------------")
	print("Enter filename (or hit Enter to go back to the main menu):")
	
	local f = io.open( "con", "r" )
	fname = f:read("*l")
	f:close()
	
	-- Read colorset file
	if fname == "" then
		err = "Filename not specified"
		nice = false
	else
		if not string.find( fname, "%.colset$" ) then
			fname = fname .. ".colset"
		end
		print( "[.] Reading " .. fname .. "...")
		f, err = io.open( fname, "r" )
		if f then
			f:close()
			dofile( fname )
		else
			nice = false
			errmsg = err
		end
	end
	
	-- Read DCPlusPlus.xml
	if nice then
		print("[.]  Reading DCPlusPlus.xml...")
		ret, err, dcppxml = colorset.readFile( colorset.settings.dcppxml)
		if not ret then
			nice = false
			errmsg = err
		else
			-- print("[.] Done.")
		end
	end
	
	-- Read formatting_settings.txt
	if nice then
		print("[.]  Reading formatting_settings.txt...")
		ret, err, fstxt = colorset.readFile( colorset.settings.fstxt)
		if not ret then
			nice = false
			errmsg = err
		else
			-- print("[.] Done.")
		end
	end
	
	-- If still nice, upgrading settings
	if nice then
		print( "[.]  Processing DCPlusPlus.xml...")
		-- Upgrading DCPlusPlus.xml ints
		for k in colorconfig.xmlint do
			local ret, err = colorset.updateXML( dcppxml, k, "int", colorconfig.xmlint[k] )
			if not ret then
				nice, errmsg = false, err
			end
		end
		-- Updating DCPlusPlus.xml strings
		-- Not used yet, but maybe could be nice later
		for k in colorconfig.xmlstring do
			local ret, err = colorset.updateXML( dcppxml, k, "string", colorconfig.xmlstring[k] )
			if not ret then
				nice, errmsg = false, err
			end
		end
	end
	if nice then
		print( "[.]  Processing formatting_settings.txt...")
		for k in colorconfig.colors do
			local ret, err = colorset.updateFS( fstxt, k , colorconfig.colors[k] )
			if not ret then
				nice , errmsg = false, err
			end
		end
	end
	
	-- Saving back the files
	if nice then
		print("[.]  Writing DCPlusPlus.xml...")
		local ret, err = colorset.saveFile( colorset.settings.dcppxml, dcppxml )
		if not ret then
			nice, errmsg = false, err
		else
			print("[.]  Writing formatting_settings.txt...")
			ret, err  = colorset.saveFile( colorset.settings.fstxt, fstxt )
			if not ret then
				nice, errmsg = false, err
			end
		end
	end

	return nice, errmsg
end

function colorset.interact()
	local needrepeat = true
	local f = io.open( "con", "r" )
	repeat
		print( "Please select from the menu:" )
		local z = f:read("*l")
		if z == "1" then
			colorset.showFiles(colorset.settings.filepat)
			print("Hit [3] to show menu")
		elseif z == "2" then
			local ret, err = colorset.loadCS()
			print("[STATUS]: " .. err)
			print("Hit [3] to show menu or [X] to exit!")
		elseif z == "3" then
			colorset.showMenu()
		elseif string.find(z, "^[Xx]$") then
			needrepeat = false
			print( "Bye." )
		else
			print( "Wrong selection! Possible values are: 1, 2, 3 (or X to quit)" )
			print( "------------------------------------------------------------" )
			colorset.showMenu()
		end
	until (not needrepeat)
	f:close()
end

--// starting script

colorset.sendWelcome()
colorset.showMenu()
colorset.interact()